package com.xayy.health.mgt.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.kawins.base.result.CheckResult;
import cn.kawins.base.result.ResultBody;
import cn.kawins.base.utils.CollUtil;
import cn.kawins.mybatis.base.BaseController;
import com.xayy.health.core.utils.FileInfosUtils;
import com.xayy.health.core.utils.LocalCache;
import com.xayy.health.mgt.model.HealthAlgorithmManage;
import com.xayy.health.mgt.model.dto.AlgorithmDto;
import com.xayy.health.mgt.model.vo.AlgorithmModelVo;
import com.xayy.health.mgt.service.AlgorithmParamService;
import com.xayy.health.mgt.service.HealthAlgorithmManageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * @author zhangxa
 */
@RestController
@RequestMapping(value = "/algorithm1")
@Api(tags = "算法管理")
public class AlgorithmController extends BaseController<HealthAlgorithmManage> {

    @Autowired
    private HealthAlgorithmManageService healthAlgorithmManageService;


    @Autowired
    private AlgorithmParamService algorithmParamService;


    /**
     * 获取算法信息分页列表
     *
     * @return ResultBody
     */
    @GetMapping("getInfo")
    @ApiOperation(value = "获取算法信息分页列表")
    public ResultBody getAlgorithmInfo() {
        return dataPage("algorithmInfoPageList");
    }

    /**
     * 算法详细信息
     * @param id 算法id
     * @return ResultBody
     */
    @GetMapping("{id}")
    @ApiOperation(value = "算法详细信息")
    public ResultBody get(@ApiParam(name = "算法id") @PathVariable("id") Long id) {
        return healthAlgorithmManageService.selectModel(id).body();
    }

    /**
     * 新建算法信息
     * @param healthAlgorithmManage 算法实体
     * @param algorithmFile 算法文件
     * @return ResultBody
     */
    @PostMapping("save")
    @ApiOperation(value = "新建算法信息")
    public ResultBody saveAlgorithmInfo(HealthAlgorithmManage healthAlgorithmManage,
                                        MultipartFile algorithmFile) {
        return healthAlgorithmManageService.saveAlgorithmInfo(healthAlgorithmManage, algorithmFile).body();
    }

    /**
     * 修改算法信息
     * @param algorithmModelVo 算法vo
     * @return 新建算法信息
     */
    @PostMapping("update")
    @ApiOperation(value = "修改算法信息", notes = "只能修改算法的状态和介绍信息")
    public ResultBody updateAlgorithmState(@RequestBody AlgorithmModelVo algorithmModelVo) {
        HealthAlgorithmManage healthAlgorithmManage1 =
                healthAlgorithmManageService.selectById(algorithmModelVo.getId());
        if (BeanUtil.isEmpty(healthAlgorithmManage1)) {
            return ResultBody.failed("当前算法不存在,无法修改!");
        }
        List<HealthAlgorithmManage> selectName =
                healthAlgorithmManageService.select(HealthAlgorithmManage.builder().algorithmName(algorithmModelVo.getAlgorithmName()).build());
        if (CollUtil.isNotEmpty(selectName)) {
            return ResultBody.failed("算法名称:" + algorithmModelVo.getAlgorithmName() + "已存在,不可重名");
        }
        HealthAlgorithmManage build = HealthAlgorithmManage.builder().id(algorithmModelVo.getId())
                .algorithmState(algorithmModelVo.getAlgorithmState())
                .algorithmDesc(algorithmModelVo.getAlgorithmDesc()).build();
//        if (healthAlgorithmManage1.getAlgorithmType() == 5){
//
//        }
        build.setAlgorithmCode(algorithmModelVo.getAlgorithmCode());
        build.setAlgorithmPath(algorithmModelVo.getAlgorithmPath());
        build.setAlgorithmFileName(algorithmModelVo.getAlgorithmFileName());
        build.setServerState(false);
        build.setAlgorithmName(algorithmModelVo.getAlgorithmName());
        build.setAlgorithmType(algorithmModelVo.getAlgorithmType());
        build.setStartServiceFile(algorithmModelVo.getStartServiceFile());
        build.setIsBuiltInAlgorithms(algorithmModelVo.getIsBuiltInAlgorithms());
        build.setTriggerType(algorithmModelVo.getTriggerType());
        build.setTrialAddr(algorithmModelVo.getTrialAddr());
        build.setPredictAddr(algorithmModelVo.getPredictAddr());
        /**关闭旧算法的进程*/
        if (healthAlgorithmManage1.getServerState() == true)
            healthAlgorithmManageService.stopAlgorithmServer(build);
        algorithmParamService.updateListByIdSelective(algorithmModelVo.getAlgorithmParams());
        healthAlgorithmManageService.updateByIdSelective(build);
        return ResultBody.success("算法状态修改成功");
    }


    /**
     * 保存上传算法信息
     * @param algorithmDto  算法入参
     * @return ResultBody
     */
    @PostMapping("saveUploadMsg")
    @ApiOperation(value = "保存上传算法信息")
    public ResultBody saveUploadMessage(@RequestBody AlgorithmDto algorithmDto) {
        healthAlgorithmManageService.saveUploadMessage(algorithmDto);
        return ResultBody.success();
    }

    /**
     * 上传文件到指定目录
     * @param file 上传文件
     * @return ResultBody
     */
    @PostMapping("uploadFile")
    @ApiOperation(value = "上传文件到指定目录")
    public ResultBody uploadFile(@RequestParam("file") MultipartFile file) {

        return ResultBody.success(FileInfosUtils.uploadFile(file));
    }


    /**
     * 算法状态上报
     * @param algorithmDto 算法入参
     * @return ResultBody
     */
    @PostMapping("stateReport")
    @ApiOperation(value = "算法状态上报")
    public ResultBody algorithmStateReport(@RequestBody AlgorithmDto algorithmDto) {

        List<HealthAlgorithmManage> algorithmManageList = healthAlgorithmManageService.selectAlgorithmByType();
        algorithmManageList.forEach(x -> {
            LocalCache.ALGORITHM_MAP.remove(x.getAlgorithmCode());
            LocalCache.ALGORITHM_MAP.put(x.getAlgorithmCode(), x);
        });
        if (!LocalCache.ALGORITHM_MAP.containsKey(algorithmDto.getAlgorithmCode())) {
            HealthAlgorithmManage healthAlgorithmManage = HealthAlgorithmManage.builder()
                    .algorithmCode(algorithmDto.getAlgorithmCode()).algorithmName(algorithmDto.getAlgorithmName())
                    .algorithmDesc(algorithmDto.getAlgorithmDesc()).algorithmPath(algorithmDto.getPath()).build();
            healthAlgorithmManageService.insert(healthAlgorithmManage);
        }
        LocalCache.TIMED_CACHE.put(algorithmDto.getAlgorithmCode(), algorithmDto.getAlgorithmName(), 10000);
        return ResultBody.success();
    }

    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除算法信息")
    public ResultBody deleteAlgorithmInfo(@ApiParam(name = "id") @PathVariable Long id) {
        HealthAlgorithmManage algorithmInfo = healthAlgorithmManageService.selectById(id);
        if (ObjectUtil.isNotNull(algorithmInfo)) {
            healthAlgorithmManageService.deleteById(id);
        }
        return ResultBody.success();
    }

    /**
     * 根据类型获取可用算法列表
     * @param type 类型
     * @return ResultBody
     */
    @GetMapping("/getAlgorithmByType/{type}")
    @ApiOperation(value = "根据类型获取可用算法列表", notes = "1:剔野,2:填充,3:平滑,4:事后诊断,5:趋势预测")
    public ResultBody getAlgorithmByType(@PathVariable @ApiParam("1:剔野,2:填充,3:平滑,4:事后诊断,5:趋势预测") Integer type) {
        List<HealthAlgorithmManage> algorithmByType = healthAlgorithmManageService.getAlgorithmByType(type);
        return ResultBody.success(algorithmByType);
    }

    /**
     * 启动算法服务
     * @param healthAlgorithmManage 算法实体
     * @return ResultBody
     */
    @PostMapping("startServer")
    @ApiOperation(value = "启动算法服务")
    public ResultBody startAlgorithmServer(@RequestBody HealthAlgorithmManage healthAlgorithmManage) {
        return healthAlgorithmManageService.startAlgorithmServer(healthAlgorithmManage).body();
    }

    /**
     * 停止算法服务
     * @param healthAlgorithmManage 算法实体
     * @return ResultBody
     */
    @PostMapping("stopServer")
    @ApiOperation(value = "停止算法服务")
    public ResultBody stopAlgorithmServer(@RequestBody HealthAlgorithmManage healthAlgorithmManage) {
        return healthAlgorithmManageService.stopAlgorithmServer(healthAlgorithmManage).body();
    }
}
